package com.sjcq.demoexample.aop;

import com.alibaba.fastjson.JSON;
import com.sjcq.demoexample.entity.SysLog;
import com.sjcq.demoexample.entity.User;
import com.sjcq.demoexample.service.SysLogService;
import org.apache.shiro.SecurityUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;

@Aspect
@Component
public class SysLogAspect {
    @Autowired
    private SysLogService sysLogService;

    // 定义切点@Pointcut,@annotation表示在注解的位置切入代码
    @Pointcut("@annotation( com.sjcq.demoexample.aop.MyLog )")
    public void logPointCut(){}

    // 切面 配置通知
    @AfterReturning("logPointCut()")
    public void saveSysLog(JoinPoint joinPoint){
        System.out.println("<<<<执行切面>>>>");

        // 保存日志
        SysLog sysLog = new SysLog();

        // 从切面织入点处通过反射机制获取织入点处的方法
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();

        // 获取切入点所在的方法
        Method method = signature.getMethod();

        // 获取操作
        MyLog myLog = method.getAnnotation(MyLog.class);
        if(myLog != null){
            String value = myLog.value();
            sysLog.setOperation(value);
        }

        // 获取请求的类名
        String className = joinPoint.getTarget().getClass().getName();
        // 获取请求的方法名
        String methodName = method.getName();
        sysLog.setMethod(className+"."+methodName);

        // 获取请求的参数
        Object[] args = joinPoint.getArgs();
        // 将参数数组转换成json
        String parmsJson = JSON.toJSONString(args);
        sysLog.setParams(parmsJson);

        // 设置创建时间
        sysLog.setCreatedtime(new Date());

        // 获取用户名
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        sysLog.setUsername(user.getUsername());

        // 获取用户IP地址
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();//这个RequestContextHolder是Springmvc提供来获得请求的东西
        HttpServletRequest request = ((ServletRequestAttributes)requestAttributes).getRequest();
        sysLog.setIp(request.getRemoteAddr());

        // 调用service保存实体类到数据库
        sysLogService.save(sysLog);
    }
}
